#include "stdafx.h"

using namespace std;
MockProbabilityModel::MockProbabilityModel(const char* aWord, int wordLength, unsigned int symbolSize) : ProbabilityModel(symbolSize)
{
	word = aWord;
	this->symbolSize = symbolSize;
	unsigned char bitMask = 0x80;
	char shift = 7;
	for (unsigned int i = 0; i < wordLength * 8;)
	{
		unsigned int symbol = 0;
		for (unsigned int j = 0; j < symbolSize && i < wordLength * 8; ++j, ++i)
		{
			symbol |= (word[i / 8] & bitMask) >> shift;
			symbol <<= 1;
			bitMask >>= 1;
			--shift;
			if (bitMask == 0)
			{
				bitMask = 0x80;
				shift = 7;
			}
		}
		symbol >>= 1;

		if (symbolsCount.find(symbol) != symbolsCount.end())
		{
			symbolsCount.find(symbol)->second += 1;
		}
		else
		{
			symbolsCount.insert(make_pair(symbol, 1));
		}
	}
	count = 0;
	for (map<unsigned int, unsigned int>::iterator it = symbolsCount.begin(); it != symbolsCount.end(); ++it)
	{
		count += it->second;
	}
}


MockProbabilityModel::~MockProbabilityModel(void)
{
}


int MockProbabilityModel::getUpperBoundForSymbol(unsigned int symbol)
{
	int bound = 0;
	map<unsigned int, unsigned int>::iterator end = symbolsCount.find(symbol);
	for (map<unsigned int, unsigned int>::iterator it = symbolsCount.begin(); it != end; ++it)
	{
		bound += it->second;
	}
	bound += end->second;
	return bound;
}

int MockProbabilityModel::getLowerBoundForSymbol(unsigned int symbol)
{
	int bound = 0;
	map<unsigned int, unsigned int>::iterator end = symbolsCount.find(symbol);
	for (map<unsigned int, unsigned int>::iterator it = symbolsCount.begin(); it != end; ++it)
	{
		bound += it->second;
	}
	return bound;
}

int MockProbabilityModel::getAllSymbolsCount()
{

	return count;
}

unsigned int MockProbabilityModel::getSymbolFromCodeNumber(unsigned int code)
{
	unsigned int bound = 0;
	for (map<unsigned int, unsigned int>::iterator it = symbolsCount.begin(); it != symbolsCount.end(); ++it)
	{
		bound += it->second;
		if (bound > code)
		{
			return it->first;
		}
	}
	return 0;
}

unsigned int MockProbabilityModel::getSymbolSize()
{
	return symbolSize;
}
